//
//  LMScreenshotHintView.swift
//  LMScreenshotHint
//
//  Created by LaiMing on 2021/4/15.
//

import Foundation
import Photos

import SnapKit



public class LMScreenshotHintView: UIView {
    
    //MARK: Attribute Declarations
    
    /// 黑色透明底
    private let blackAplhaView = UIView.init()
    
    /// 截图显示
    private let screenshotImageView = UIImageView.init()

    /// 视图宽度
    private let viewSizeWidth:CGFloat = 110
    
    /// 视图自动消失时间
    public var autoDismissSeconds:Float = 4.0

    
    /// 视图消失回调
    public var dismissFinishBlock:( ()->Void )?
    
    //MARK: Getter & Setter
    
    //MARK: WillSet & Didset
    
    //MARK: Lift Cycle
    public override init(frame: CGRect) {
        super.init(frame: frame)
        
        initUI()
    }
    
    public required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    //MARK: Init Data & UI
    /// 设置UI
    private func initUI() {
        

        //
        backgroundColor = .clear
        
        //
        blackAplhaView.backgroundColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.6)
        blackAplhaView.layer.cornerRadius = 5
        blackAplhaView.layer.masksToBounds = true
        addSubview(blackAplhaView)
        blackAplhaView.snp.makeConstraints { (make) in
            make.width.equalTo(viewSizeWidth)
            make.top.bottom.equalToSuperview()
            make.right.equalToSuperview().offset(viewSizeWidth)
        }
        
        
        
        //
        screenshotImageView.image = LMTools.getScreenshotImage()
        screenshotImageView.isUserInteractionEnabled = true
        screenshotImageView.backgroundColor = .white
        screenshotImageView.layer.masksToBounds = true
        screenshotImageView.layer.cornerRadius = 5
        screenshotImageView.clipsToBounds = true
        screenshotImageView.contentMode = .scaleAspectFill
        blackAplhaView.addSubview(screenshotImageView)
        screenshotImageView.snp.makeConstraints { (make) in
            make.top.left.equalToSuperview().offset(8)
            make.right.equalToSuperview().offset(-8)
            make.height.equalTo(screenshotImageView.snp.width)
        }
        
        
        //
        let editScreenShotTap:UITapGestureRecognizer = UITapGestureRecognizer.init()
        editScreenShotTap.addTarget(self, action: #selector(goToEditScreenShotViewAction))
        screenshotImageView.addGestureRecognizer(editScreenShotTap)
        
        
        //
        let feedbackButton = UIButton.init(type: .custom)
        feedbackButton.layer.masksToBounds = true
        feedbackButton.layer.cornerRadius = 5
        feedbackButton.backgroundColor = UIColor.init(red: 37/255, green: 37/255, blue: 37/255, alpha: 1)
        feedbackButton.setTitleColor(.white, for: .normal)
        feedbackButton.titleLabel?.font = .italicSystemFont(ofSize: 13)
        feedbackButton.setTitle("反馈问题", for: .normal)
        feedbackButton.setImage(LMTools.filePathImageNamed(name: "icon_feedback_edit_white"), for: .normal)
        feedbackButton.addTarget(self, action: #selector(goToFeedbackQuestionAction), for: .touchUpInside)
        blackAplhaView.addSubview(feedbackButton)
        feedbackButton.snp.makeConstraints { (make) in
            make.left.right.equalTo(screenshotImageView)
            make.top.equalTo(screenshotImageView.snp.bottom).offset(8)
            make.height.equalTo(34)
        }
        
        
        //
        let shareButton = UIButton.init(type: .custom)
        shareButton.layer.masksToBounds = true
        shareButton.layer.cornerRadius = 5
        shareButton.backgroundColor = feedbackButton.backgroundColor
        shareButton.setTitleColor(.white, for: .normal)
        shareButton.titleLabel?.font = feedbackButton.titleLabel?.font
        shareButton.setTitle("分享页面", for: .normal)
        shareButton.setImage(LMTools.filePathImageNamed(name: "icon_feedback_share_white"), for: .normal)
        shareButton.addTarget(self, action: #selector(shareViewAction), for: .touchUpInside)
        blackAplhaView.addSubview(shareButton)
        shareButton.snp.makeConstraints { (make) in
            make.left.right.height.equalTo(feedbackButton)
            make.top.equalTo(feedbackButton.snp.bottom).offset(8)
        }
        
        //右滑手势
        let swipeGestureRight = UISwipeGestureRecognizer(target: self, action: #selector(dismiss))
        swipeGestureRight.direction = .right
        addGestureRecognizer(swipeGestureRight)
    }
    
    //MARK: Private Method

    //MARK: Public Method
    
    /// 展示
    @objc public func showView() {

        let windowView = LMTools.getCurrentWindow()
        
        windowView.addSubview(self)
        self.snp.makeConstraints { (make) in
            make.width.equalTo(viewSizeWidth+15)
            make.height.equalTo(191)
            make.top.equalTo(windowView.snp.centerY)
            make.right.equalToSuperview()
        }
        
        isUserInteractionEnabled = false
        
        layoutIfNeeded()
        

        UIView.animate(withDuration: 0.25) { [weak self] in
            
            self?.blackAplhaView.snp.updateConstraints { (make) in
                make.right.equalToSuperview().offset(-15)
            }

            self?.layoutIfNeeded()
            
        } completion: { [weak self] (finish:Bool) in
            
            if finish == true {
                
                self?.isUserInteractionEnabled = true
                
                if self?.autoDismissSeconds ?? 0 > 0 {
                    
                    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + TimeInterval(self?.autoDismissSeconds ?? 1)) {

                        self?.dismiss()
                    }
                }

            }
        }
        
    }
    
    /// 关闭视图
    @objc public func dismiss() {
        
        isUserInteractionEnabled = false
        
        if dismissFinishBlock != nil {
            dismissFinishBlock!()
        }
        
        UIView.animate(withDuration: 0.3,
                                delay: 0.1,
                                options: [.curveEaseOut]) { [weak self] in
             
            
            self?.blackAplhaView.snp.updateConstraints { (make) in
                make.right.equalToSuperview().offset( self?.viewSizeWidth ?? 0 )
            }

            self?.layoutIfNeeded()
            
        } completion: { [weak self] (finish:Bool) in

            if finish == true {
                
                self?.removeFromSuperview()
            }
    
        }

    }
    
    //MARK: Event & Action
    
    /// 跳转到图片编辑
    @objc private func goToEditScreenShotViewAction() {
        
        DispatchQueue.main.async { [weak self] in
            
            let vc = SMScreenshotEditController.init()
            vc.originImage = self?.screenshotImageView.image
            
            let nav = UINavigationController.init(rootViewController: vc)
            nav.modalPresentationStyle = .fullScreen
            
            LMTools.getCurrentController()!.present(nav, animated: true) {

            }
            
            self?.dismiss()
        }
        
    }
    
    /// 反馈问题按钮响应
    @objc private func goToFeedbackQuestionAction() {
        
        if LMScreenshotSington.sharedInstance?.hintViewFeedbackBlock != nil {
            
            LMScreenshotSington.sharedInstance?.hintViewFeedbackBlock!(screenshotImageView.image ?? UIImage())
            
        }else{
            
            goToEditScreenShotViewAction()
        }
    }
    
    /// 分享页面
    @objc private func shareViewAction() {
        
        if LMScreenshotSington.sharedInstance?.hintViewShareBlock != nil {
            LMScreenshotSington.sharedInstance?.hintViewShareBlock!(screenshotImageView.image ?? UIImage())
        }
    }
}





/// 截图编辑控制器
fileprivate class SMScreenshotEditController: UIViewController {
    
    //MARK: Attribute Declarations
    
    /// 图片放大缩小底view
    private let imageScrollView = UIScrollView.init(frame: .init(x: 0,
                                                                 y: lmTabBarH,
                                                                 width: lmScreenWidth,
                                                                 height: lmScreenHeight - lmTabBarH - lmSafeBottomH))
    
    /// 图片显示
    private var displayImageView = LMDrawTouchPointImageView.init()
    
    
    /// 撤回按钮
    private let revokeButton = UIButton.init(type: .custom)
    
    /// 模糊按钮
    private let fuzzyButton = UIButton.init(type: .custom)
    
    /// 画笔按钮
    private let strokeButton = UIButton.init(type: .custom)


    /// 底部操作工具栏
    private lazy var bottomToolBarView:UIView = {
        
        //
        let bgView = UIView.init()
        bgView.isHidden = true
        bgView.backgroundColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.7)
        view.addSubview(bgView)
        bgView.snp.makeConstraints { (make) in
            make.left.right.bottom.equalToSuperview()
            make.height.equalTo(lmTabBarH + 20)
        }

        //
        let stackView = UIStackView.init(arrangedSubviews: [revokeButton,fuzzyButton,strokeButton])
        stackView.axis = .horizontal
        stackView.spacing = 0
        stackView.alignment = .center
        stackView.distribution = .fillEqually
        bgView.addSubview(stackView)
        stackView.snp.makeConstraints { (make) in
            make.top.bottom.equalToSuperview()
            make.left.equalToSuperview().offset(25)
            make.right.equalToSuperview().offset(-25)
        }
        
        
        //
        revokeButton.setImage(LMTools.filePathImageNamed(name: "icon_screenshotEdit_tool_return"), for: .normal)
        revokeButton.setImage(LMTools.filePathImageNamed(name: "icon_screenshotEdit_tool_return_select"), for: .highlighted)
        revokeButton.setTitle("撤回", for: .normal)
        revokeButton.setTitle("撤回", for: .highlighted)
        revokeButton.setTitleColor(.white, for: .normal)
        revokeButton.setTitleColor(UIColor.init(red: 64/255.0, green: 193/255.0, blue: 127/255.0, alpha: 1), for: .highlighted)
        revokeButton.titleLabel?.font = .italicSystemFont(ofSize: 11)
        revokeButton.addTarget(self, action: #selector(revokeButtonAction), for: .touchUpInside)
        revokeButton.snp.makeConstraints { (make) in
            make.top.bottom.equalToSuperview()
        }
        
        revokeButton.lmImagePosition(style: .top, spacing: 6)
        
        
        //
        fuzzyButton.setImage(LMTools.filePathImageNamed(name: "icon_screenshotEdit_tool_fuzzy"), for: .normal)
        fuzzyButton.setImage(LMTools.filePathImageNamed(name: "icon_screenshotEdit_tool_fuzzy_select"), for: .selected)
        fuzzyButton.setImage(LMTools.filePathImageNamed(name: "icon_screenshotEdit_tool_fuzzy_select"), for: .highlighted)
        fuzzyButton.setTitle("模糊", for: .normal)
        fuzzyButton.setTitle("模糊", for: .highlighted)
        fuzzyButton.setTitleColor(.white, for: .normal)
        fuzzyButton.setTitleColor(UIColor.init(red: 64/255.0, green: 193/255.0, blue: 127/255.0, alpha: 1), for: .highlighted)
        fuzzyButton.setTitleColor(UIColor.init(red: 64/255.0, green: 193/255.0, blue: 127/255.0, alpha: 1), for: .selected)
        fuzzyButton.titleLabel?.font = revokeButton.titleLabel?.font
        fuzzyButton.addTarget(self, action: #selector(fuzzyButtonAction), for: .touchUpInside)
        fuzzyButton.snp.makeConstraints { (make) in
            make.top.bottom.equalToSuperview()
        }
        
        fuzzyButton.lmImagePosition(style: .top, spacing: 6)
        
        
        //
        strokeButton.setImage(LMTools.filePathImageNamed(name: "icon_screenshotEdit_tool_stroke"), for: .normal)
        strokeButton.setImage(LMTools.filePathImageNamed(name: "icon_screenshotEdit_tool_stroke_select"), for: .selected)
        strokeButton.setImage(LMTools.filePathImageNamed(name: "icon_screenshotEdit_tool_stroke_select"), for: .highlighted)
        strokeButton.setTitle("画笔", for: .normal)
        strokeButton.setTitle("画笔", for: .highlighted)
        strokeButton.setTitleColor(.white, for: .normal)
        strokeButton.setTitleColor(UIColor.init(red: 64/255.0, green: 193/255.0, blue: 127/255.0, alpha: 1), for: .highlighted)
        strokeButton.setTitleColor(UIColor.init(red: 64/255.0, green: 193/255.0, blue: 127/255.0, alpha: 1), for: .selected)
        strokeButton.titleLabel?.font = revokeButton.titleLabel?.font
        strokeButton.addTarget(self, action: #selector(strokeButtonAction), for: .touchUpInside)
        strokeButton.snp.makeConstraints { (make) in
            make.top.bottom.equalToSuperview()
        }
        
        strokeButton.lmImagePosition(style: .top, spacing: 6)
        
        return bgView
    }()

    /// 原始图片(外部传入)
    public var originImage:UIImage?
    
    
    
    //MARK: Getter & Setter
    
    //MARK: WillSet & Didset
    
    //MARK: Lift Cycle
    override func viewDidLoad() {
        super.viewDidLoad()
        
        initUi()
    }
    

    override func viewDidLayoutSubviews() {
        
        super.viewDidLayoutSubviews()
        
        if let image = displayImageView.image {
            
            setScrollViewScale(use: image.size,
                                    containerSize: imageScrollView.bounds.size)
            
            setImageViewCenterIn(scrollView: imageScrollView)
        }
    }
    
    //MARK: Init Data & UI
    
    /// 设置ui
    private func initUi() {
        
        title = LMScreenshotSington.sharedInstance?.editControllerTitle
        view.backgroundColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.5)
        
        //
        let gobackButton = UIButton.init(frame: CGRect.init(x: 0, y: 0, width: 44, height: 44))
        gobackButton.contentHorizontalAlignment = .left
        gobackButton.setImage(LMTools.filePathImageNamed(name: "icon_goback_arrow_black"), for: .normal)
        gobackButton.addTarget(self, action: #selector(gobackAction), for: .touchUpInside)
        gobackButton.titleEdgeInsets = UIEdgeInsets.init(top: 0, left: 10, bottom: 0, right: 0)
        navigationItem.leftBarButtonItem = UIBarButtonItem.init(customView: gobackButton)
        
        
        //
        let commitNavButton = UIButton.init(frame: CGRect.init(x: 0, y: 0, width: 60, height: 25))
        commitNavButton.layer.masksToBounds = true
        commitNavButton.layer.cornerRadius = 12.5
        commitNavButton.backgroundColor = UIColor.init(red: 64/255.0, green: 193/255.0, blue: 127/255.0, alpha: 1)
        commitNavButton.setTitle("提交", for: .normal)
        commitNavButton.setTitleColor(.white, for: .normal)
        commitNavButton.titleLabel?.font = .italicSystemFont(ofSize: 15)
        commitNavButton.addTarget(self, action: #selector(commitNavButtonAction), for: .touchUpInside)
        navigationItem.rightBarButtonItem = UIBarButtonItem.init(customView: commitNavButton)
        
        
        //
        imageScrollView.delegate = self
        imageScrollView.maximumZoomScale = 3
        imageScrollView.minimumZoomScale = 3
        imageScrollView.translatesAutoresizingMaskIntoConstraints = false
        imageScrollView.showsHorizontalScrollIndicator = false
        imageScrollView.showsVerticalScrollIndicator = false
        imageScrollView.backgroundColor = .clear
        imageScrollView.canCancelContentTouches = false//是否可以中断touches
//        imageScrollView.delaysContentTouches = false;//是否延迟touches事件
        view.addSubview(imageScrollView)
        
        //
        displayImageView = LMDrawTouchPointImageView.init(newImage: originImage ?? UIImage(),
                                                          newFrame: imageScrollView.bounds,
                                                          lineWidth: LMScreenshotSington.sharedInstance?.stokeLineWidth ?? 4,
                                                          lineColor: LMScreenshotSington.sharedInstance?.stokeColor ?? .red)
        displayImageView.contentMode = .scaleAspectFit
        displayImageView.isUserInteractionEnabled = true
        imageScrollView.addSubview(displayImageView)
        
        
        //
        let toolBarViewTapGes:UITapGestureRecognizer = UITapGestureRecognizer.init()
        toolBarViewTapGes.addTarget(self, action: #selector(toolBarViewTapGesAction))
        imageScrollView.addGestureRecognizer(toolBarViewTapGes)
        
        
        
        //
        setScrollViewScale(use: originImage?.size ?? CGSize.zero,
                           containerSize: imageScrollView.bounds.size)
        setImageViewCenterIn(scrollView: imageScrollView)
        
    }
    

    
    //MARK: Private Method
    
    /// 控制器消失
    private func controllerDismiss( _ finalImage:UIImage = UIImage() ) {
        
        dismiss(animated: true) {
            
            if LMScreenshotSington.sharedInstance?.editControllerCommitBlock != nil {
                LMScreenshotSington.sharedInstance?.editControllerCommitBlock!(finalImage)
            }
        }
    }
    
    /// 把imageView的居中到scrollView中心
    private func setImageViewCenterIn(scrollView:UIScrollView) {
        
        let offsetX = (scrollView.bounds.width > scrollView.contentSize.width) ? (scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5 : 0.0
        let offsetY = (scrollView.bounds.size.height > scrollView.contentSize.height) ? (scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5 : 0.0
        
        displayImageView.center = CGPoint(x:scrollView.contentSize.width * 0.5 + offsetX,
                                          y:scrollView.contentSize.height * 0.5 + offsetY)
    
    }
    
    /// 用image size和容器size来调整scroll view的缩放比例和image view 的size
    ///
    /// - Parameters:
    ///   - imageSize: 图片大小
    ///   - cSize: 容器大小
    private func setScrollViewScale(use imageSize:CGSize,containerSize cSize:CGSize) {
        
        displayImageView.frame.size = cSize
        
//        if displayImageView.frame.size == CGSize.zero {
//            displayImageView.frame.size = imageSize
//        }
        
//        print("displayImageView.frame.size-->\(displayImageView.frame.size)")
        
        imageScrollView.contentSize = imageSize
                   
        let cRate = cSize.width / cSize.height // 容器的宽高比
        let iRate = imageSize.width / imageSize.height // 图片的宽高比
        
        if imageSize.width <= cSize.width && imageSize.height <= cSize.height {
            
            imageScrollView.minimumZoomScale = 1.0
            imageScrollView.maximumZoomScale = 2.0
            
        }else {
            
            let minScale:CGFloat
            
            if iRate > cRate {
                minScale = cSize.width / imageSize.width
            }else{
                minScale = cSize.height / imageSize.height
            }
            imageScrollView.minimumZoomScale = minScale
            imageScrollView.maximumZoomScale = minScale * 2
        }
        
        imageScrollView.zoomScale = imageScrollView.minimumZoomScale
    }
    
    
    
    //MARK: Public Method
    
    //MARK: Event & Action
    
    /// 提交按钮响应
    @objc private func commitNavButtonAction() {

        let finalImage:UIImage = displayImageView.getImage() ?? UIImage()
        
        
        guard Bundle.main.value(forKeyPath: "infoDictionary.NSPhotoLibraryAddUsageDescription") != nil && Bundle.main.value(forKeyPath: "infoDictionary.NSPhotoLibraryUsageDescription") != nil else {

            print("LMScreenshotSington: info.plist没有添加相册权限\nPrivacy - Photo Library Additions Usage Description\nPrivacy - Photo Library Usage Description")
            
            controllerDismiss(finalImage)
            
            return
        }
        
        
        if PHPhotoLibrary.authorizationStatus() == .notDetermined {
                    
            PHPhotoLibrary.requestAuthorization( { (status) in
                    
                if status == .authorized {
                    
//                    print("点同意")
                    
                    //保存到相册
                    UIImageWriteToSavedPhotosAlbum(finalImage, nil, nil, nil)
                    
                    self.controllerDismiss(finalImage)
                    
                } else if status == .denied || status == .restricted {
                    
//                    print("点拒绝")
                    
                    self.controllerDismiss(finalImage)
                    
                }else {
                    
                    self.controllerDismiss(finalImage)
                }
                    
            })
        
        } else {
            
//            print("无权限")
            
            controllerDismiss(finalImage)
        }
        
    }

    
    /// 返回按钮响应
    @objc private func gobackAction() {
        
        if (presentingViewController != nil) && navigationController?.viewControllers.count == 1 {
            
            dismiss(animated: true, completion: nil)
            
        }else {
            
            navigationController?.popViewController(animated: true)
        }
    
    }
    
    /// 屏幕单击事件响应  (底部工具栏 显示/隐藏)
    @objc private func toolBarViewTapGesAction() {
        
        bottomToolBarView.isHidden = !bottomToolBarView.isHidden
    }
    
    
    /// 撤回按钮响应
    @objc private func revokeButtonAction() {
        
        displayImageView.revokeScreen()
    }
    
    /// 马赛克按钮响应
    @objc private func fuzzyButtonAction() {
        
        strokeButton.isSelected = false
        fuzzyButton.isSelected = !fuzzyButton.isSelected
        
        if fuzzyButton.isSelected == true {
            
            displayImageView.currentOperation = .MosaicFuzzy
            
        }else{
            
            displayImageView.currentOperation = .None
        }
    }
    
    /// 画笔按钮响应
    @objc private func strokeButtonAction() {
        
        fuzzyButton.isSelected = false
        strokeButton.isSelected = !strokeButton.isSelected
        
        if strokeButton.isSelected == true {
            
            displayImageView.currentOperation = .Srtoke
            
        }else{
            
            displayImageView.currentOperation = .None
        }
    }
    
    //MARK: Network Request
}


// MARK: - UIScrollViewDelegate
extension SMScreenshotEditController:UIScrollViewDelegate {
    
    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
        
        displayImageView
    }
    
    func scrollViewDidZoom(_ scrollView: UIScrollView) {
        
        setImageViewCenterIn(scrollView: scrollView)

    }
}
